package com.dave.gd.common.util;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

/**
 * IO工具类
 * 
 * @author linhz
 */
public class IOUtils {
    // private static ILogger log = LoggerFactory.getLogger(IOUtils.class);
    
    /**
     * 关闭对象（不抛异常）
     * 
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (IOException ioe) {
        }
    }
    
    /**
     * 
     * @param input
     * @param output
     * @throws IOException
     */
    public static void copy(InputStream input, OutputStream output) throws IOException {
        copy(input, output, false);
    }
    
    /**
     * Get the contents of an InputStream as a String using the default
     * character encoding of the platform.
     * 
     * @param in
     * @return
     */
    public static String toString(InputStream in, boolean close) throws Exception {
        try {
            return org.apache.commons.io.IOUtils.toString(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            // log.error("", e);
            throw e;
            
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        
    }
    
    /**
     * 没有关闭流的连接
     * 
     * @param in
     * @param encoding
     * @return
     */
    public static String toString(InputStream in, String encoding, boolean close) throws Exception {
        try {
            
            return org.apache.commons.io.IOUtils.toString(in, encoding);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw e;
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        
    }
    
    public static void main(String[] args) throws Exception {
        
        // byte[] ii="123456789".getBytes("gbk");
        // System.out.println(ByteUtils.format(ii));
        // ByteArrayInputStream bi=new
        // ByteArrayInputStream("1234567890".getBytes());
        //
        //
        // bi.read();
        // bi.read();
        //
        //
        // byte[] ss=IOUtils.readFully(bi, 3, false);
        // System.out.println(ByteUtils.format(ss));
        // byte[] oo=new
        // byte[]{(byte)bi.read(),(byte)bi.read(),(byte)bi.read()};
        // System.out.println(ByteUtils.format(oo));
        // bi.close();
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(bout);
        dout.writeInt(1);
        dout.writeShort(2);
        dout.writeUTF("abc");
        dout.writeByte(3);
        System.out.println(bout.toByteArray().length);
        FileUtils.write("c:/test.txt", bout.toByteArray());
        
    }
    
    /**
     * 读固定长度的字节,如果少于给定的字节,抛出异常
     * 
     * @param in
     * @param readLen
     * @param close
     * @return
     * @throws Exception
     */
    public static byte[] readFully(InputStream in, int readLen, boolean close) throws IOException {
        
        // DataInputStream s=new DataInputStream(in);
        
        byte[] bs = new byte[readLen];
        // in.read(bs);
        // 读满一个数组
        int bytesRead = 0;
        try {
            
            // BufferedInputStream br=new BufferedInputStream(in);
            while (bytesRead < readLen) {
                
                int result = in.read(bs, bytesRead, readLen - bytesRead);
                
                if (result == -1)
                    break;
                
                bytesRead += result;
                
            }
            if (bytesRead < readLen) {
                // bs = Arrays.copyOfRange(bs, 0, bytesRead);
                throw new IOException("haven't  read given" + " number[" + readLen + "]bytes");
            }
        } catch (IOException ex) {
            throw ex;
            // bs = new byte[0];
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        return bs;
    }
    
    /**
     * 读固定长度的字符,如果少于给定的字节,抛出异常
     * 
     * @param in
     * @param readLen
     * @param close
     * @return
     * @throws Exception
     */
    public static char[] readFully(Reader in, int readLen, boolean close) throws IOException {
        
        char[] bs = new char[readLen];
        // in.read(bs);
        // 读满一个数组
        int bytesRead = 0;
        try {
            while (bytesRead < readLen) {
                
                int result = in.read(bs, bytesRead, readLen - bytesRead);
                
                if (result == -1)
                    break;
                
                bytesRead += result;
                
            }
            if (bytesRead < readLen) {
                throw new IOException("haven't  read given" + " number[" + readLen + "]chars");
            }
        } catch (IOException ex) {
            throw ex;
            // bs = new char[0];
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        return bs;
    }
    
    public static byte[] toByteArray(InputStream in, boolean close) throws Exception {
        try {
            
            return org.apache.commons.io.IOUtils.toByteArray(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw e;
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        
    }
    
    public static byte[] toByteArray(Reader in, String charset, boolean close) throws Exception {
        try {
            return org.apache.commons.io.IOUtils.toByteArray(in, charset);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            // log.error("", e);
            throw e;
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        
    }
    
    /**
     * 把input流拷到output流，所有的流都不会关闭
     * 
     * @param input
     * @param output
     * @return
     * @throws IOException
     */
    public static int copy(InputStream input, OutputStream output, boolean close)
        throws IOException {
        try {
            return org.apache.commons.io.IOUtils.copy(input, output);
        } finally {
            if (close) {
                input.close();
                output.close();
            }
        }
    }
    
    /**
     * 把input流拷贝到output，encoding为转换时利用的编码，所有的流都不会关闭
     * 
     * @param input
     * @param output
     * @param encoding
     * @throws IOException
     */
    public static void copy(InputStream input, Writer output, String encoding, boolean close)
        throws IOException {
        try {
            org.apache.commons.io.IOUtils.copy(input, output, encoding);
        } finally {
            if (close) {
                input.close();
                output.close();
            }
        }
    }
    
    /**
     * 把input流拷贝到output流，encoding为转换时的编码，所有的流都不会关闭
     * 
     * @param input
     * @param output
     * @param encoding
     * @throws IOException
     */
    public static void copy(Reader input, OutputStream output, String encoding, boolean close)
        throws IOException {
        try {
            org.apache.commons.io.IOUtils.copy(input, output, encoding);
        } finally {
            if (close) {
                input.close();
                output.close();
            }
        }
    }
    
    /**
     * 比较两个流的内容是否相等，所有的流都不会关闭
     * 
     * @param input1
     * @param input2
     * @return
     * @throws IOException
     */
    public static boolean contentEquals(InputStream input1, InputStream input2, boolean close)
        throws IOException {
        try {
            return org.apache.commons.io.IOUtils.contentEquals(input1, input2);
        } finally {
            if (close) {
                input1.close();
                input2.close();
            }
        }
    }
    
    /**
     * 比较两个流的内容是否相等，所有的流都不会关闭
     * 
     * @param input1
     * @param input2
     * @return
     * @throws IOException
     */
    public static boolean contentEquals(Reader input1, Reader input2, boolean close)
        throws IOException {
        try {
            return org.apache.commons.io.IOUtils.contentEquals(input1, input2);
        } finally {
            if (close) {
                input1.close();
                input2.close();
                
            }
        }
    }
    
    /**
     * 跳过多少个自己，不会关闭流
     * 
     * @param input
     * @param toSkip
     * @return
     * @throws IOException
     */
    public static long skip(InputStream input, long toSkip, boolean close) throws IOException {
        try {
            return org.apache.commons.io.IOUtils.skip(input, toSkip);
        } finally {
            if (close)
                input.close();
            
        }
    }
    
    /**
     * 跳过多少个字符，不会关闭流
     * 
     * @param input
     * @param toSkip
     * @return
     * @throws IOException
     */
    public static long skip(Reader input, long toSkip, boolean close) throws IOException {
        
        try {
            return org.apache.commons.io.IOUtils.skip(input, toSkip);
        } finally {
            if (close)
                input.close();
        }
    }
    
    public static String toString(Reader in, boolean close) throws Exception {
        try {
            return org.apache.commons.io.IOUtils.toString(in);
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw e;
        } finally {
            try {
                if (close)
                    in.close();
            } catch (IOException e) {
                
            }
        }
        
    }
    
    public static void close(InputStream in) throws Exception {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                throw e;
                // e.printStackTrace();
            }
        }
    }
    
    public static void close(OutputStream out) throws Exception {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                throw e;
                // e.printStackTrace();
            }
        }
    }
    
    public static void close(Writer out) throws Exception {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                throw e;
                // e.printStackTrace();
            }
        }
    }
    
    public static void close(Reader in) throws Exception {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                throw e;
                // e.printStackTrace();
            }
        }
    }
}
